﻿#ifndef __INC_QGDRV_D11_CNV_H__
#define __INC_QGDRV_D11_CNV_H__

#ifdef _MSC_VER
#pragma once
#endif

namespace D11Convert
{
	// color format
	inline bool DetectColor(qgColorFormat& fmt, DXGI_FORMAT& devfmt)
	{
		// D11은 16비트 24비트 컬러를 지원하지 않기 땜시 32비트로 바꾸거나 취소
		// 알파없는 컬러도 지원하지 않기 때문에 다 알파 쓴다
		// D11.1에서 16비트 컬러 지원...하지만 쓸일은 없지.
		switch (fmt)
		{
			case QGCF8_L:		devfmt = DXGI_FORMAT_R8_UNORM; return false;
			case QGCF16_L:		devfmt = DXGI_FORMAT_R16_UNORM; return false;
			case QGCF32_BGR:	// 지원안함 BGRA로
			case QGCF32_BGRA:	devfmt = DXGI_FORMAT_R8G8B8A8_UNORM; fmt = QGCF32_BGRA; return true;
			case QGCF16_RGB:	// 지원안함 32RGB로
			case QGCF32_RGB:	devfmt = DXGI_FORMAT_B8G8R8X8_UNORM; fmt = QGCF32_RGB; return false;
			case QGCF16_RGBA:	// 지원안함 32RGBA로 ,  DXGI1.1용 즉 윈8용....인가 아닌가 테스트해야함
			case QGCF32_RGBA:	devfmt = DXGI_FORMAT_B8G8R8A8_UNORM; fmt = QGCF32_RGBA; return true;
			case QGCF16F_R:		devfmt = DXGI_FORMAT_R16_FLOAT; return false;
			case QGCF64F_BGRA:	devfmt = DXGI_FORMAT_R16G16B16A16_FLOAT; return true;
			case QGCF32F_R:		devfmt = DXGI_FORMAT_R32_FLOAT; return false;
			case QGCF128F_BGRA:	devfmt = DXGI_FORMAT_R32G32B32A32_FLOAT; return true;
			case QGCF_DXT1:		devfmt = DXGI_FORMAT_BC1_UNORM; return false;
			case QGCF_DXT2:		devfmt = DXGI_FORMAT_BC2_UNORM; return false;
			case QGCF_DXT3:		devfmt = DXGI_FORMAT_BC3_UNORM; return false;
			case QGCF_DXT4:		devfmt = DXGI_FORMAT_BC4_UNORM; return false;
			case QGCF_DXT5:		devfmt = DXGI_FORMAT_BC5_UNORM; return false;
			default:			devfmt = DXGI_FORMAT_UNKNOWN; return false;
		}
	}

	//
	inline qgColorFormat ColorFormat(DXGI_FORMAT fmt)
	{
		switch (fmt)
		{
			case DXGI_FORMAT_R8_UNORM:				return QGCF8_L;
			case DXGI_FORMAT_R16_UNORM:				return QGCF16_L;
			case DXGI_FORMAT_R8G8B8A8_UNORM:		return QGCF32_BGRA;
			case DXGI_FORMAT_B8G8R8A8_UNORM:		return QGCF32_RGBA;	// DXGI1.1용 즉 D11용... 테스트 필요
			case DXGI_FORMAT_B8G8R8X8_UNORM:		return QGCF32_RGB;
			case DXGI_FORMAT_R16_FLOAT:				return QGCF16F_R;
			case DXGI_FORMAT_R16G16B16A16_FLOAT:	return QGCF64F_BGRA;
			case DXGI_FORMAT_R32_FLOAT:				return QGCF32F_R;
			case DXGI_FORMAT_R32G32B32A32_FLOAT:	return QGCF128F_BGRA;
			case DXGI_FORMAT_BC1_UNORM:				return QGCF_DXT1;
			case DXGI_FORMAT_BC2_UNORM:				return QGCF_DXT2;
			case DXGI_FORMAT_BC3_UNORM:				return QGCF_DXT3;
			case DXGI_FORMAT_BC4_UNORM:				return QGCF_DXT4;
			case DXGI_FORMAT_BC5_UNORM:				return QGCF_DXT5;
			default:								return QGCF_NONE;
		}
	}

	// 
	inline bool TestCompressedFormat(DXGI_FORMAT fmt)
	{
		switch (fmt)
		{
			case DXGI_FORMAT_BC1_UNORM:
			case DXGI_FORMAT_BC2_UNORM:
			case DXGI_FORMAT_BC3_UNORM:
			case DXGI_FORMAT_BC4_UNORM:
			case DXGI_FORMAT_BC5_UNORM:
				return true;
		}

		return false;
	}

	// 
	inline D3D11_PRIMITIVE_TOPOLOGY Topology(qgTopology tpg)
	{
		switch (tpg)
		{
			case QGTPG_POINT_LIST:	return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
			case QGTPG_LINE_LIST:	return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
			case QGTPG_LINE_STRIP:	return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
			case QGTPG_TRI_LIST:	return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
			//case QGTPG_TRI_STRIP:
			default:				return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
		}
	}

	//
	inline D3D11_COMPARISON_FUNC ComparisonOp(qgCmpOp cop)
	{
		switch (cop)
		{
			case QGCOP_LE:		return D3D11_COMPARISON_LESS;
			case QGCOP_EQ:		return D3D11_COMPARISON_EQUAL;
			case QGCOP_LEQ:		return D3D11_COMPARISON_LESS_EQUAL;
			case QGCOP_GR:		return D3D11_COMPARISON_GREATER;
			case QGCOP_NEQ:		return D3D11_COMPARISON_NOT_EQUAL;
			case QGCOP_GEQ:		return D3D11_COMPARISON_GREATER_EQUAL;
			case QGCOP_ALWAYS:	return D3D11_COMPARISON_ALWAYS;
			//case QGCOP_NEVER:
			default:			return D3D11_COMPARISON_NEVER;
		}
	}

	//
	inline D3D11_COMPARISON_FUNC SamplerOp(qgCmpOp cop)
	{
		switch (cop)
		{
			case QGCOP_LE:
			case QGCOP_LEQ:		return D3D11_COMPARISON_LESS;
			default:			return D3D11_COMPARISON_NEVER;
		}
	}

	//
	inline D3D11_BLEND_OP BlendOp(qgBlendOp op)
	{
		switch (op)
		{
			case QGBLO_SUB:		return D3D11_BLEND_OP_SUBTRACT;
			case QGBLO_RSUB:	return D3D11_BLEND_OP_REV_SUBTRACT;
			case QGBLO_MIN:		return D3D11_BLEND_OP_MIN;
			case QGBLO_MAX:		return D3D11_BLEND_OP_MAX;
			//case QGBLO_ADD:
			default:			return D3D11_BLEND_OP_ADD;
		}
	}

	//
	inline D3D11_BLEND BlendFactor(qgBlendFactor v)
	{
		switch (v)
		{
			case QGBLF_ONE:		return D3D11_BLEND_ONE;
			case QGBLF_SC:		return D3D11_BLEND_SRC_COLOR;
			case QGBLF_SC_INV:	return D3D11_BLEND_INV_SRC_COLOR;
			case QGBLF_SA:		return D3D11_BLEND_SRC_ALPHA;
			case QGBLF_SA_INV:	return D3D11_BLEND_INV_SRC_ALPHA;
			case QGBLF_DA:		return D3D11_BLEND_DEST_ALPHA;
			case QGBLF_DA_INV:	return D3D11_BLEND_INV_DEST_ALPHA;
			case QGBLF_DC:		return D3D11_BLEND_DEST_COLOR;
			case QGBLF_DC_INV:	return D3D11_BLEND_INV_DEST_COLOR;
			case QGBLF_SAS:		return D3D11_BLEND_SRC_ALPHA_SAT;
			//case QGBLF_ZERO:
			default:			return D3D11_BLEND_ZERO;
		}
	}

	//
	inline D3D11_FILTER Filter(qgFilter v, bool iscmp)
	{
		if (iscmp)
		{
			switch (v)
			{
				case QGFLT_MAG_MIN_MIP_POINT:				return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
				case QGFLT_MAG_MIN_POINT_MIP_LINEAR:		return D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR;
				case QGFLT_MAG_POINT_MIN_LINEAR_MIP_POINT:	return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT;
				case QGFLT_MAG_POINT_MIN_MIP_LINEAR:		return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
				case QGFLT_MAG_LINEAR_MIN_MIP_POINT:		return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT;
				case QGFLT_MAG_LINEAR_MIN_POINT_MIP_LINEAR:	return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR;
				case QGFLT_MAG_MIN_LINEAR_MIP_POINT:		return D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
				case QGFLT_MAG_MIN_MIP_LINEAR:				return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
				case QGFLT_ANISOTROPIC:						return D3D11_FILTER_COMPARISON_ANISOTROPIC;
				case QGFLTX_LINEAR:							return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
				//case QGFLTX_POINT:
				default:									return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
			}
		}
		else
		{
			switch (v)
			{
				case QGFLT_MAG_MIN_MIP_POINT:				return D3D11_FILTER_MIN_MAG_MIP_POINT;
				case QGFLT_MAG_MIN_POINT_MIP_LINEAR:		return D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
				case QGFLT_MAG_POINT_MIN_LINEAR_MIP_POINT:	return D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
				case QGFLT_MAG_POINT_MIN_MIP_LINEAR:		return D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
				case QGFLT_MAG_LINEAR_MIN_MIP_POINT:		return D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
				case QGFLT_MAG_LINEAR_MIN_POINT_MIP_LINEAR:	return D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
				case QGFLT_MAG_MIN_LINEAR_MIP_POINT:		return D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
				case QGFLT_MAG_MIN_MIP_LINEAR:				return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
				case QGFLT_ANISOTROPIC:						return D3D11_FILTER_ANISOTROPIC;
				case QGFLTX_LINEAR:							return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
				//case QGFLTX_POINT:
				default:									return D3D11_FILTER_MIN_MAG_MIP_POINT;
			}
		}
	}

	//
	inline D3D11_TEXTURE_ADDRESS_MODE Address(qgAddress v)
	{
		switch (v)
		{
			case QGADR_WRAP:	return D3D11_TEXTURE_ADDRESS_WRAP;
			case QGADR_MIRROR:	return D3D11_TEXTURE_ADDRESS_MIRROR;
			case QGADR_BORDER:	return D3D11_TEXTURE_ADDRESS_BORDER;
			case QGADR_ONCE:	return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
			//case QGADR_CLAMP:
			default:			return D3D11_TEXTURE_ADDRESS_CLAMP;
		}
	}

	//
	inline D3D11_STENCIL_OP StencilOp(qgStencilOp v)
	{
		switch (v)
		{
			case QGSOP_ZERO:	return D3D11_STENCIL_OP_ZERO;
			case QGSOP_REPLACE:	return D3D11_STENCIL_OP_REPLACE;
			case QGSOP_SAT_INC:	return D3D11_STENCIL_OP_INCR_SAT;
			case QGSOP_SAT_DEC:	return D3D11_STENCIL_OP_DECR_SAT;
			case QGSOP_INVERT:	return D3D11_STENCIL_OP_INVERT;
			case QGSOP_INC:		return D3D11_STENCIL_OP_INCR;
			case QGSOP_DEC:		return D3D11_STENCIL_OP_DECR;
			//case QGSOP_KEEP:
			default:			return D3D11_STENCIL_OP_KEEP;
		}
	}

	//
	inline DXGI_FORMAT IndexStrideFormat(kint stride)
	{
		return stride == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
	}
}

#endif	// __INC_QGDRV_D11_CNV_H__

